home *** CD-ROM | disk | FTP | other *** search
- /* Widgets for the Midnight Commander, Tk interface code
- Copyright (C) 1994 Radek Doulik
- Copyright (C) 1994, 1995 Miguel de Icaza
- Copyright (C) 1995 Jakub Jelinek
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- TODO: Destroy all the command names that are created for each
- widget during runtime.
-
- */
- #include <config.h>
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- #include <ctype.h>
- #include "tkmain.h"
- #include "dlg.h"
-
- static char
- widget_number (Widget *w)
- {
- Dlg_head *h = w->parent;
- const int count = h->count;
- Widget_Item *item;
- int i;
-
- item = h->first;
- for (i = 0; i < count; i++){
- if (item->widget == w)
- return i;
- item = item->next;
- }
- /* Actually, if we get this far, this message should not appear */
- fprintf (stderr, "Inconsistent widget\n");
- exit (1);
- }
-
- /* Returns a new command prefixed with an x:
- x.query.$the_frame.b0
-
- for the command of the query dialog box button 0
-
- This allow us to control the widget with the command:
- .query.$the_frame.b0
-
- and to access the C code callback with the:
- x.query.$the_frame.b0
- command.
- */
- char *
- tk_new_command (widget_data parent, void *widget,
- tcl_callback callback, char id)
- {
- char buffer [12];
- Widget *w = (Widget *) widget;
- char *cmd, *format;
-
- if (((char *) parent) [1] == 0)
- format = "%s%c%d";
- else
- format = ".%s%c%d";
-
- /* wdata holds the frame information, it will be replaced with the
- * the widget command name
- */
- sprintf (buffer, format, w->frame, id, widget_number (w));
- cmd = copy_strings ("x", (char *)parent, buffer, 0);
- w->wdata = (widget_data) cmd;
-
- if (callback)
- Tcl_CreateCommand (interp, cmd, callback, w, NULL);
- return cmd;
- }
-
-
- /* Button routines */
-
- /* Called from the Tcl/Tk program when a button has been pressed */
- static int
- tk_button_callback (ClientData cd, Tcl_Interp *interp, int argc, char *argv [])
- {
- WButton *b = (WButton *) cd;
- Dlg_head *h = (Dlg_head *) b->widget.parent;
- int stop = 0;
-
- if (b->callback)
- stop = (*b->callback)(b->action, b->callback_data);
- if (!b->callback || stop){
- h->running = 0;
- h->ret_value = b->action;
- }
- return TCL_OK;
- }
-
- /* Removes the [ and ] from the text mode button version */
-
- static char *
- clean_button (char *text)
- {
- static char buffer [20];
- char *p, *q;
-
- if ((strlen (text) + 1) >= sizeof (buffer)){
- return text;
- }
- strcpy (buffer, text);
- for (p = buffer; *p == ' ' || *p == '['; p++)
- ;
- for (q = buffer + strlen (buffer); q > buffer &&
- (!*q || *q == ' ' || *q == ']'); q--);
- *(++q) = 0;
-
- return p;
- }
-
- void
- x_button_set (WButton *b, char *text)
- {
- char *cmd = wtcl_cmd (b->widget);
-
- tk_evalf ("%s configure -text {%s}", cmd+1, clean_button (text));
- }
-
- /* Creates the button $parent.$newname and executes $newname command */
- int
- x_create_button (Dlg_head *h, widget_data parent, WButton *b)
- {
- char *cmd;
-
- cmd = tk_new_command (parent, b, tk_button_callback, 'b');
- tk_evalf ("newbutton %s %s {%s}", cmd+1, cmd, clean_button (b->text));
- return 1;
- }
-
-
-
- /* Radio button routines */
- static int
- tk_radio_callback (ClientData cd, Tcl_Interp *interp, int argc, char *argv [])
- {
- WRadio *r = (WRadio *) cd;
-
- if (STREQ (argv [1], "select")){
- r->pos = r->sel = atoi (argv [2]);
- }
- (r->widget.callback)(r->widget.parent, r, WIDGET_KEY, ' ');
- return TCL_OK;
- }
-
- int
- x_create_radio (Dlg_head *h, widget_data parent, WRadio *r)
- {
- int i;
- char *cmd;
-
- cmd = tk_new_command (parent, r, tk_radio_callback, 'r');
- tk_evalf ("newradio %s", cmd+1);
-
- for (i = 0; i < r->count; i++){
- tk_evalf ("radio_item %d {%s} %s %d", i, r->texts [i], cmd,
- r->sel == i);
- }
- return 1;
- }
-
- /* Checkbuttons routines */
-
- static int
- tk_check_callback (ClientData cd, Tcl_Interp *interp, int argc, char *argv [])
- {
- WCheck *c = (WCheck *) cd;
- Dlg_head *h = c->widget.parent;
-
- (*c->widget.callback)(h, c, WIDGET_KEY, ' ');
- return TCL_OK;
- }
-
- int
- x_create_check (Dlg_head *h, widget_data parent, WCheck *c)
- {
- char *cmd;
-
- cmd = tk_new_command (parent, c, tk_check_callback, 'c');
- tk_evalf ("newcheck %s %s {%s} %d", cmd+1, cmd, c->text, c->state);
-
- return 1;
- }
-
-
- /* Input line */
-
- /* This callback command accepts the following commands:
- **
- ** $win mouse x-position
- ** $win setmark x-position
- */
- static int
- tk_input_callback (ClientData cd, Tcl_Interp *interp, int argc, char *av [])
- {
- Gpm_Event e;
- WInput *in = (WInput *) cd;
-
- if (strcmp (av [1], "mouse") == 0){
- e.x = atoi (av [2]) + 1;
- e.y = 0;
- e.type = GPM_DOWN;
- input_event (&e, (WInput *) cd);
- return TCL_OK;
- } else if (strcmp (av [1], "setmark") == 0){
- in->mark = in->point;
- return TCL_OK;
- }
-
- return TCL_OK;
- }
-
- void
- tk_update_input (WInput *in)
- {
- char *name = wtcl_cmd (in->widget);
- int p;
-
- if (!name)
- return;
-
- name++;
- if (in->is_password){
- tk_evalf ("%s delete 0 end", name);
- tk_evalf ("%s insert end {*secret*}", name);
- p = 9;
- } else {
- tk_evalf ("entry_save_sel %s", name);
- if (in->inserted_one && isascii (in->inserted_one) && in->inserted_one > ' '){
- tk_evalf ("%s insert insert {%c}", name, in->inserted_one);
- in->inserted_one = 0;
- } else {
- tk_evalf ("%s delete 0 end", name);
- tk_evalf ("%s insert end {%s}", name, in->buffer);
- }
- p = in->point;
- }
- tk_evalf ("%s icursor %d; entry_restore_sel %s", name, p, name);
- }
-
- int
- x_create_input (Dlg_head *h, widget_data parent, WInput *in)
- {
- char *cmd;
-
- cmd = tk_new_command (parent, in, tk_input_callback, 'i');
- tk_evalf ("newinput %s {%s}", cmd+1, in->buffer ? in->buffer: "");
- return 1;
- }
-
- void
- x_listbox_select_nth (WListbox *l, int nth)
- {
- if (!wtcl_cmd (l->widget))
- return;
-
- tk_evalf ("listbox_sel %s %d", wtk_win (l->widget), nth);
- }
-
- void
- x_listbox_delete_nth (WListbox *l, int nth)
- {
- tk_evalf ("%s delete %d", wtk_win (l->widget), nth);
- }
-
- int
- x_create_listbox (Dlg_head *h, widget_data parent, WListbox *l)
- {
- char *cmd;
- int i;
- WLEntry *e;
-
- cmd = tk_new_command (parent, l, 0, 'x');
- tk_evalf ("listbox %s -width %d -selectmode single", cmd+1, l->widget.cols);
-
- /* As Jakub said on his very fine xvwidget.c: the user could add some
- * entries to the listbox before the tk-listbox was created, so we have
- * to add it manually :-)
- */
- i = 0;
- if ((e = l->list) == NULL)
- return 1;
-
- do {
- tk_evalf ("%s insert %d {%s}", cmd+1, i, e->text);
- if (e == l->current)
- x_listbox_select_nth (l, i);
- e = e->next;
- i++;
- } while (e != l->list);
- return 1;
- }
-
- void
- x_list_insert (WListbox *l, WLEntry *p, WLEntry *e)
- {
- int i;
- char *t = e->text;
-
- if (wtcl_cmd (l->widget) == NULL)
- return;
-
- for (i = 0; p != NULL && p != e; e = e->next, i++)
- ;
- tk_evalf ("%s insert %d {%s}", wtk_win (l->widget), i-1, t);
- }
-
- int
- x_create_label (Dlg_head *g, widget_data parent, WLabel *l)
- {
- char *cmd;
-
- cmd = tk_new_command (parent, l, 0, 'l');
- tk_evalf ("label %s -text {%s}", cmd+1, l->text);
- return 1;
- }
-
-
- void
- x_label_set_text (WLabel *label, char *text)
- {
- char *lname;
-
- if (!wtcl_cmd (label->widget))
- return;
-
- tk_evalf ("%s configure -text {%s}", wtk_win (label->widget),
- text ? text : "");
- }
-
-
- static int
- tk_buttonbar_callback (ClientData cd, Tcl_Interp *in, int ac, char *av [])
- {
- WButtonBar *bb = (WButtonBar *) cd;
- Dlg_head *h = (Dlg_head *) bb->widget.parent;
- int which = atoi (av [1]);
-
- (*bb->labels [which].function)(bb->labels [which].data);
- return TCL_OK;
- }
-
- int
- x_create_buttonbar (Dlg_head *h, widget_data parent, WButtonBar *bb)
- {
- char *cmd;
- int i;
-
- cmd = tk_new_command (parent, bb, tk_buttonbar_callback, 'n');
- tk_evalf ("frame %s", cmd+1);
- for (i = 0; i < 10; i++){
- tk_evalf ("newbutton %s.%d {%s %d} {%d %s}", cmd+1, i, cmd, i, i+1,
- bb->labels [i].text ? bb->labels [i].text : "");
- tk_evalf ("%s.%d configure -padx 1", cmd+1, i);
- tk_evalf ("pack %s.%d -side left -fill x -expand 1 -ipady 0",
- cmd+1, i);
- }
- return 1;
- }
-
- void
- x_redefine_label (WButtonBar *bb, int idx)
- {
- if (!bb->widget.wdata)
- return;
-
- if (!*(char *) bb->widget.wdata)
- return;
-
- if (!bb->labels [idx-1].text)
- return;
- tk_evalf ("%s.%d configure -text {%d %s}",
- wtk_win (bb->widget), idx-1, idx, bb->labels [idx-1].text);
- }
-
- /* destructor for the Tk widgets */
- void
- x_destroy_cmd (void *w)
- {
- Widget *widget = (Widget *)w;
-
- if (widget->wdata){
- Tcl_DeleteCommand (interp, wtcl_cmd (*widget));
- tk_evalf ("destroy %s", wtk_win (*widget));
- free (wtcl_cmd (*widget));
- }
- }
-
- int
- x_find_buttonbar_check (WButtonBar *bb, Widget *paneletc)
- {
- return (strcmp ((char *) bb->widget.wcontainer,
- (char *)paneletc->wcontainer));
- }
-
- /* The only parameter accepted is the size of the widget width */
- static int
- tk_gauge_callback (ClientData cd, Tcl_Interp *in, int ac, char *av [])
- {
- WGauge *g = (WGauge *) cd;
-
- g->pixels = atoi (av [1]);
- return TCL_OK;
- }
-
- void
- x_create_gauge (Dlg_head *h, widget_data parent, WGauge *g)
- {
- char *cmd;
-
- cmd = tk_new_command (parent, g, tk_gauge_callback, 'g');
- tk_evalf ("newgauge %s", cmd+1);
- }
-
- static void
- x_gauge_display (WGauge *g)
- {
- tk_evalf ("%s coords gauge 0 0 %d 90", wtk_win (g->widget),
- (int) (g->current*g->pixels)/g->max);
- }
-
- void
- x_gauge_show (WGauge *g)
- {
- tk_evalf ("gauge_%s %s", g->shown ? "shown":"hidden", wtk_win (g->widget));
- if (g->shown)
- x_gauge_display (g);
- }
-
- void
- x_gauge_set_value (WGauge *g, int max, int current)
- {
- if (g->shown)
- x_gauge_display (g);
- }
-